/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ssp.net;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import ssp.ResourceManager;
import ssp.SimulationManager;
import ssp.utility.MersenneTwisterRNG;

/**
 * シミュレーション中のネットワークコンポーネントを管理するクラス
 * @author yamazaki
 */
public class NWcomponentManager implements ResourceManager {
    
    /**
     * シミュレーション中で唯一のクラスインスタンス
     */
    private final static NWcomponentManager INSTANCE = new NWcomponentManager();
    
    /**
     * シミュレーション中のネットワークコンポーネントのリスト
     */
    private List<NWcomponent> nwComponentList;
    
    /**
     * コンストラクタ<br>
     * シングルトンのためprivateアクセス
     */
    private NWcomponentManager() {
        init();
        SimulationManager.register(this);
    }

    @Override
    public final void init() {
        this.nwComponentList = new ArrayList<NWcomponent>();
    }

    /**
     * @return the INSTANCE
     */
    public static NWcomponentManager getINSTANCE() {
        return INSTANCE;
    }
    
    /**
     * 指定のネットワークコンポーネントを管理に追加する
     * @param nwComponent 追加するネットワークコンポーネント
     */
    public void add(NWcomponent nwComponent) {
        this.nwComponentList.add(nwComponent);
    }
    
    /**
     * 管理中のネットワークコンポーネント数を返す
     * @return 管理中のネットワークコンポーネント数
     */
    public int getNWcomponentNum() {
        return this.nwComponentList.size();
    }
    
    /**
     * 指定のインデックスに対応するネットワークコンポーネントを返す
     * @param index インデックス
     * @return ネットワークコンポーネント
     */
    public NWcomponent getNWcomponent(int index) {
        return this.nwComponentList.get(index);
    }
    
    /**
     * @return the NWcomponentList
     */
    public List<NWcomponent> getNWcomponentList() {
        return new ArrayList<NWcomponent>(this.nwComponentList);
    }
    
    /**
     * 指定数のネットワークコンポーネントのリストをシャッフルして返す
     * @param num ネットワークコンポーネント数
     * @return シャッフルしたネットワークコンポーネントのリスト
     */
    public List<NWcomponent> getShuffledList(int num) {
        if(this.nwComponentList.size() < num) {
            throw new IllegalArgumentException();
        }
        List<NWcomponent> newList = new ArrayList<NWcomponent>(nwComponentList);
        Collections.shuffle(newList, MersenneTwisterRNG.getINSTANCE());
        return newList.subList(0, num);
    }
    
    /**
     * ランダムなネットワークコンポーネントを返す
     * @return ネットワークコンポーネント
     */
    public NWcomponent getRandomNWcomponent() {
        return getNWcomponent(MersenneTwisterRNG.getINSTANCE().nextInt(getNWcomponentNum()));
    }
    
}
